/**
 * 给定一个有r/e/d构成的字符串，两类操作：
 * 1 p c: 将p位置改为c
 * 2 s e: 问[s, e]范围内最少修改多少个字母可以变为好串。
 * 好串指没有长度不小于2的回文子串
 * 由于字母表只有3个合法的字母，因此会发现所谓好串一共只有6种模式：
 * 012012012...
 * 021021021...
 * ...
 * 即只能按照某种排列不停的重复，否则必然存在回文子串
 * 因此第2类操作实际上就是问：[s, e]与6种模式的不同字母的数量最少是多少
 * 修改一个字母，最多只影响一个位置。因此用6个树状数组记录。假定第b个树状数组记录S与第b个模式不同字母的数量
 * 第2个操作查询即可。
 * 第1个操作有可能加一、减一、或不变。
 */
#include <bits/stdc++.h>
using namespace std;

using llt = long long;

struct FenwickTree{ // 树状数组

using value_type = long long int;
using vec_type = vector<value_type>;

int n;
vec_type c;

FenwickTree() = default;

static int lowbit(int x){return x & -x;}

void init(int nn){this->c.assign((this->n=nn) + 1, 0);}

void modify(int pos, value_type delta){
    for(int i=pos;i<=this->n;i+=lowbit(i)) this->c[i] += delta;
}

value_type query(int pos)const{
    value_type ans = 0;
    for(int i=pos;i;i-=lowbit(i)) ans += this->c[i];
    return ans;
}

value_type query(int s, int e)const{return this->query(e) - this->query(s - 1);}

}Bt[6];

int N;
int Q;
string S;

array<string, 6> Standard;

void work(){
    cin >> N >> Q >> S;
    S = " " + S;

    string s = "der";
    int k = 0;
    do{
        Standard[k++] = s;
    }while(next_permutation(s.begin(), s.end()));

    int b = 0;
    for(const auto & s : Standard){
        auto & bt = Bt[b++];
        bt.init(N);
        for(int i=1,k=0;i<=N;++i,k=(k+1)%3){
            if(S[i] != s[k]){
                bt.modify(i, 1);
            }
        }
    }
    
    for(int c,q=1;q<=Q;++q){
        cin >> c;
        if(2 == c){
            int s, e; cin >> s >> e;
            llt ans = e - s + 1;
            for(const auto & b : Bt){
                ans = min(ans, b.query(s, e));
            }
            cout << ans << "\n";
        }else{
            int pos; 
            char ch;
            cin >> pos >> ch;
            char & och = S[pos];
            int idx = (pos - 1) % 3;
            for(int i=0;i<6;++i){
                bool pre = och == Standard[i][idx];
                bool cur = ch == Standard[i][idx];
                if(cur != pre){
                    if(pre){
                        Bt[i].modify(pos, 1);
                    }else{
                        Bt[i].modify(pos, -1);
                    }
                }
            }
            och = ch;
        }
    }

    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase; 
    while(nofkase--) work();
    return 0;
}
